package com.gin.kotlin.gf2gamecommunity.composable.index

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gin.kotlin.gf2gamecommunity.R
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.livedata.CachedLiveData
import com.gin.kotlin.gf2gamecommunity.base.composable.MyImage
import com.gin.kotlin.gf2gamecommunity.base.composable.SimpleAlertDialog
import com.gin.kotlin.gf2gamecommunity.database.entity.GF2Account
import com.gin.kotlin.gf2gamecommunity.routes.ExchangeItemRoute
import com.gin.kotlin.gf2gamecommunity.routes.ScoreLogRoute
import com.gin.kotlin.gf2gamecommunity.viewmodel.DailyViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.UserViewModel
import com.gin.kotlin.response.Res
import com.gin.kotlin.response.task.CurrentTaskList.TaskInfo
import com.gin.kotlin.response.task.MonthSignInStatus
import kotlinx.coroutines.launch

/**
 * 首页日常：签到、积分中心、道具兑换
 * @param viewModel DailyViewModel
 * @param modifier Modifier
 */
@Composable
fun IndexDaily(
    viewModel: DailyViewModel = viewModel(),
    userViewModel: UserViewModel = viewModel(),
    modifier: Modifier = Modifier,
    onNavigateToExchangeItem: (route: ExchangeItemRoute) -> Unit,
    onNavigateToScoreLog: (route: ScoreLogRoute) -> Unit
) {
    val account = App.INSTANCE.currentAccount() ?: return
    val force = account.uid != userViewModel.currentUid.value

    Column(modifier = Modifier
        .fillMaxSize()
        .padding(16.dp)) {
        // 用户信息
        UserInfo(viewModel, userViewModel, force, onNavigateToExchangeItem = onNavigateToExchangeItem, onNavigateToScoreLog = onNavigateToScoreLog)
        HorizontalDivider(modifier = Modifier.height(2.dp))
        // 月签到
        Month(viewModel.month, force)
        HorizontalDivider(modifier = Modifier.height(2.dp))
        //  任务列表
        Tasks(viewModel, force)
        HorizontalDivider(modifier = Modifier.height(2.dp))
        // 自动开关
        AutoSwitch(account)
    }
}

@Composable
private fun UserInfo(
    viewModel: DailyViewModel,
    userViewModel: UserViewModel,
    force: Boolean,
    onNavigateToExchangeItem: (route: ExchangeItemRoute) -> Unit,
    onNavigateToScoreLog: (route: ScoreLogRoute) -> Unit
) {
    val currentData = viewModel.current
    // 当前签到
    val current = currentData.liveData.observeAsState()
    // 用户信息
    val userInfoState = userViewModel.cUser.liveData.observeAsState()

    currentData.fetch(force)
    userViewModel.fetchCurrentUserInfo()

    Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
        Row {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                // 用户头像，昵称
                userInfoState.value?.apply {
                    MyImage(model = avatar, modifier = Modifier
                        .clip(CircleShape)
                        .width(60.dp))
                    Text(nickName)
                }
            }
            Column {
                //     经验
                userInfoState.value?.apply {
                    Text("Lv. $level", fontWeight = FontWeight.Bold)
                    Text("经验: $exp / $nextLvExp")
                    AssistChip(onClick = {
                        onNavigateToScoreLog(ScoreLogRoute())
                    }, label = { Text("积分: $score") }, leadingIcon = {
                        Icon(painterResource(R.drawable.ic_history_24), contentDescription = "查询积分记录", Modifier.size(AssistChipDefaults.IconSize))
                    })
                }
            }
        }
        Column {
            Button(onClick = { viewModel.signIn() }, enabled = current.value?.hasSignIn == false) { Text(if (current.value?.hasSignIn == false) "签到" else "已签到") }
            Button(onClick = { onNavigateToExchangeItem(ExchangeItemRoute()) }) { Text("兑换") }
        }
    }
}

@Composable
private fun Month(monthData: CachedLiveData<Res<MonthSignInStatus>, MonthSignInStatus>, force: Boolean) {
    val month = monthData.liveData.observeAsState()
    monthData.fetch(force)
    val state = rememberLazyListState()

    month.value?.apply {
        Column {
            Text("签到周期: $startDate ~ $endDate")
            Text("已签到: $signInDays 天")

            LazyRow(state = state) {
                itemsIndexed(items = list) { index, item ->
                    Box {
                        Box(contentAlignment = Alignment.BottomEnd, modifier = Modifier.graphicsLayer {
                            alpha = if (index < signInDays) 0.3f else 1f
                        }) {
                            MyImage(item.itemPic)
                            Text("x${item.itemCount}")
                        }
                        Text((index + 1).toString())
                    }
                }
            }
        }

        LaunchedEffect(key1 = null) {
            launch {
                state.scrollToItem(signInDays - 1)
            }
        }

    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun Tasks(viewModel: DailyViewModel, force: Boolean) {
    val taskData = viewModel.tasks
    // 任务列表
    val tasks = taskData.liveData.observeAsState()
    var showDaily by remember { mutableStateOf(false) }
    var showMore by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()

    // 根据查询结果，设置任务列表的初始状态
    taskData.fetch(force, expire = 60, onSuccess = { data ->
        data.apply {
            showDaily = dailyTask.any { it.completeCount != it.maxCompleteCount }
            showMore = moreTask.any { it.completeCount != it.maxCompleteCount }
        }
    })

    fun taskProgress(tasks: List<TaskInfo>) = "${tasks.sumOf { it.completeCount }}/${tasks.sumOf { it.maxCompleteCount }}"

    val messages = remember { mutableStateListOf<String>() }
    var showDailyAllDialog by remember { mutableStateOf(false) }
    tasks.value?.apply {
        Column {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text("日常任务 ${taskProgress(dailyTask)}", fontWeight = FontWeight.Bold, fontSize = 20.sp, modifier = Modifier.clickable { showDaily = !showDaily })
                IconButton(
                    enabled = dailyTask.any { it.completeCount != it.maxCompleteCount },
                    onClick = {
                        scope.launch {
                            showDailyAllDialog = true
                            viewModel.dailyAll { messages.add(it) }
                        }
                    }) {

                    Icon(painterResource(R.drawable.ic_airplanemode_active_24), contentDescription = "一键任务")
                }
            }

            if (showDaily) LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                items(items = dailyTask) { TaskItem(it) }
            }

            HorizontalDivider(modifier = Modifier.height(2.dp))

            Text("更多任务 ${taskProgress(moreTask)}", fontWeight = FontWeight.Bold, fontSize = 20.sp, modifier = Modifier.clickable { showMore = !showMore })

            if (showMore) LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                items(items = moreTask) { TaskItem(it) }
            }
        }
    }
    when {
        showDailyAllDialog -> {
            SimpleAlertDialog(onDismissRequest = { showDailyAllDialog = false }) {
                LazyColumn { items(items = messages) { Text(it) } }
            }
        }
    }
}

@Composable
private fun TaskItem(taskInfo: TaskInfo) {
    Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
        Column {
            Text("${taskInfo.taskName}  (${taskInfo.completeCount}/${taskInfo.maxCompleteCount})", fontWeight = FontWeight.Bold, fontSize = 18.sp)
            Text(taskInfo.taskContext, modifier = Modifier.graphicsLayer { alpha = 0.7f })
        }
        if (taskInfo.completeCount == taskInfo.maxCompleteCount) {
            Icon(Icons.Filled.CheckCircle, contentDescription = null)
        }
    }
}

/**
 * 自动开关：签到，日常任务，道具兑换
 * @param account GF2Account
 */
@Composable
private fun AutoSwitch(account: GF2Account) {
    var autoSignIn by remember { mutableStateOf(account.autoSignIn) }
    var autoDailyTask by remember { mutableStateOf(account.autoDailyTask) }
    var autoExchange by remember { mutableStateOf(account.autoExchange) }

    val dao = App.INSTANCE.database.gF2AccountDao()
    var entity = account.copy()

    Column {
        Text("自动开关", fontWeight = FontWeight.Bold, fontSize = 20.sp)
        Spacer(modifier = Modifier.height(4.dp))
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text("自动签到: ")
            Switch(checked = autoSignIn, onCheckedChange = {
                autoSignIn = it
                entity = entity.copy(autoSignIn = it)
                dao.add(entity)
            })
        }
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text("日常任务: ")
            Switch(checked = autoDailyTask, onCheckedChange = {
                autoDailyTask = it
                entity = entity.copy(autoDailyTask = it)
                dao.add(entity)
            })
        }
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text("道具兑换: ")
            Switch(checked = autoExchange, onCheckedChange = {
                autoExchange = it
                entity = entity.copy(autoExchange = it)
                dao.add(entity)
            })
        }

    }
}